import React, {
    useState,
    useRef,
    forwardRef,
    useImperativeHandle,
    useEffect,
} from 'react';
import { createRoot } from 'react-dom/client';
import { Modal, ModalProps } from 'antd';
import { DialogConfig, DialogHandler } from '@/types/dialog';
import { isFunction } from '@/utils/is';
// 对话框组件
const Dialog = forwardRef<
    DialogHandler,
    {
        config: DialogConfig;
        onDestroy: () => void;
    }
>(({ config, onDestroy }, ref) => {
    const [isOpen, setIsOpen] = useState(true);
    const [currentConfig, setCurrentConfig] = useState(config);
    const isClosingRef = useRef(false);
    const headerRef = useRef<HTMLDivElement>(null);
    // 拖拽相关状态
    const isDragging = useRef(false);
    const startPos = useRef({ x: 0, y: 0 });
    const modalPos = useRef({ x: 0, y: 0 });
    // 立即关闭对话框
    const immediateClose = () => {
        setIsOpen(false);
        isClosingRef.current = false;
    };

    // 带动画的关闭
    const closeWithAnimation = () => {
        if (isClosingRef.current) return;
        isClosingRef.current = true;
        setTimeout(() => {
            immediateClose();
            onDestroy();
        }, 300);
    };

    const getAntModal = (node: any) => {
        if (node.className && node.className.split(' ').includes('ant-modal')) {
            return node;
        } else {
            return getAntModal(node.parentNode);
        }
    };

    // 添加/移除全局鼠标事件监听
    useEffect(() => {
        if (!currentConfig.draggable || !headerRef.current) return;
        const modalElement = getAntModal(headerRef.current);
        if (!modalElement) return;

        const header = headerRef.current;
        let modalRect = modalElement.getBoundingClientRect();

        // 初始化位置
        modalElement.style.position = 'absolute';
        modalElement.style.left = `${modalRect.left}px`;
        modalElement.style.top = `${modalRect.top}px`;
        modalElement.style.margin = '0';
        modalElement.style.transform = 'none';
        const handleMouseDown = (e: MouseEvent) => {
            isDragging.current = true;
            startPos.current = { x: e.clientX, y: e.clientY };
            modalRect = modalElement.getBoundingClientRect();
            modalPos.current = { x: modalRect.left, y: modalRect.top };
            document.body.style.userSelect = 'none';
        };

        const handleMouseMove = (e: MouseEvent) => {
            if (!isDragging.current) return;

            const dx = e.clientX - startPos.current.x;
            const dy = e.clientY - startPos.current.y;

            let newX = modalPos.current.x + dx;
            let newY = modalPos.current.y + dy;

            // 边界检查
            newX = Math.max(
                0,
                Math.min(newX, window.innerWidth - modalRect.width),
            );
            newY = Math.max(
                0,
                Math.min(newY, window.innerHeight - modalRect.height),
            );

            modalElement.style.left = `${newX}px`;
            modalElement.style.top = `${newY}px`;
        };

        const handleMouseUp = () => {
            isDragging.current = false;
            document.body.style.userSelect = '';
        };

        header.addEventListener('mousedown', handleMouseDown);
        header.addEventListener('mousemove', handleMouseMove);
        document.addEventListener('mouseup', handleMouseUp);

        return () => {
            header.removeEventListener('mousedown', handleMouseDown);
            header.removeEventListener('mousemove', handleMouseMove);
            document.removeEventListener('mouseup', handleMouseUp);
        };
    }, [currentConfig.draggable]);

    // 更新对话框配置
    const update = (newConfig: Partial<DialogConfig>) => {
        if (!isClosingRef.current) {
            setCurrentConfig((prev) => ({ ...prev, ...newConfig }));
        }
    };

    // 暴露 API
    useImperativeHandle(ref, () => ({
        close: closeWithAnimation,
        update,
    }));

    // 处理配置
    const processedConfig: DialogConfig = {
        ...currentConfig,
        open: isOpen,
        onCancel: (e) => {
            if (currentConfig.onCancel && isFunction(currentConfig.onCancel)) {
                currentConfig.onCancel(closeWithAnimation);
            } else {
                closeWithAnimation();
            }
        },
        onOk: (e) => {
            if (currentConfig.onOk && isFunction(currentConfig.onOk)) {
                currentConfig.onOk(closeWithAnimation);
            } else {
                closeWithAnimation();
            }
        },
    };

    // 解构配置
    const {
        header,
        content,
        children,
        footer,
        draggable = true,
        onCancel,
        onOk,
        ...modalProps
    } = processedConfig;
    // 自定义头部 - 添加拖拽区域
    const customHeader = (
        <div
            ref={headerRef}
            className="custom-dialog-header"
            style={{
                cursor: draggable ? 'move' : 'default',
                padding: '16px 24px',
                margin: '-16px -24px 0 -24px',
            }}
        >
            {header || processedConfig.title}
        </div>
    );
    return (
        <Modal
            {...modalProps}
            open={isOpen}
            className={`custom-dialog ${processedConfig.className || ''}`}
            title={customHeader}
            footer={footer}
            styles={{
                header: { ...modalProps.headerStyle },
                content: { ...modalProps.contentStyle },
                footer: {
                    textAlign: 'center',
                    ...modalProps.footerStyle,
                },
            }}
            onCancel={onCancel as ModalProps['onCancel']}
            onOk={onOk as ModalProps['onOk']}
        >
            {content || children}
        </Modal>
    );
});

// 渲染对话框的函数
export const UseDialog = (config: DialogConfig): DialogHandler => {
    // 创建容器
    const container = document.createElement('div');
    document.body.appendChild(container);

    // 创建根实例
    const root = createRoot(container);
    const dialogRef = React.createRef<DialogHandler>();
    const onDestroy = () => {
        setTimeout(() => {
            root.unmount();
            if (document.body.contains(container)) {
                document.body.removeChild(container);
            }
        }, 400);
    };
    // 渲染对话框
    root.render(
        <Dialog
            config={{
                draggable: true,
                cancelText: '取消',
                okText: '确定',
                ...config,
            }}
            onDestroy={onDestroy}
            ref={dialogRef}
        />,
    );

    // 返回对话框处理程序
    return {
        close: () => {
            if (dialogRef.current) {
                dialogRef.current.close();
            }
        },
        update: (newConfig: Partial<DialogConfig>) => {
            if (dialogRef.current) {
                dialogRef.current.update(newConfig);
            }
        },
    };
};
export default UseDialog;
